#include <errno.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>

int create_listening_socket(int port)
{
    int sockfd;
    int optval = 1;
    struct sockaddr_in addr;

    // 1. 创建套接字
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return -1;
    }

    // 2. 设置 SO_REUSEPORT 选项！！！（关键步骤）
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval))) {
        perror("setsockopt (SO_REUSEPORT)");
        close(sockfd);
        return -1;
    }

    // 3. 设置 SO_REUSEADDR 通常也一起设置
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval))) {
        perror("setsockopt (SO_REUSEADDR)");
        close(sockfd);
        return -1;
    }

    // 4. 绑定地址和端口
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);  // 绑定所有网卡
    addr.sin_port = htons(port);               // 绑定指定端口

    if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) == -1) {
        perror("bind");
        close(sockfd);
        return -1;
    }

    // 5. 开始监听
    if (listen(sockfd, SOMAXCONN) == -1) {
        perror("listen");
        close(sockfd);
        return -1;
    }

    return sockfd;
}
